package ru.amse.podolsky.fractalarch.model;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author Алексей
 */

//package ru.amse.podolsky.fractalarch;
import java.awt.image.*;
import java.io.*;
import javax.imageio.*;

public class Domen {
    
    //Constants
    private final int domenSize = IParams.DOMEN_SIZE;
    private final int numberOfDomenParams = 6;
    private final int maxDelta = 65535;
    
    private final int xcoordinate;
    private final int ycoordinate;
    private final int[][] pixels;
    
    public final DomenParams domenParams; 
    
    public Domen(){
       this.xcoordinate = 0;
       this.ycoordinate = 0;
       this.pixels = new int[this.domenSize][this.domenSize];
       
       this.domenParams = new DomenParams();
       this.domenParams.domenXCoord = this.xcoordinate;
       this.domenParams.domenYCoord = this.ycoordinate;
       this.domenParams.sameBlockNumber = 0;
       this.domenParams.shift = 0;
       this.domenParams.numberOfConversion = 0;
       this.domenParams.testDelta = this.maxDelta;
    }
    
    Domen(Block block, int xposition, int yposition){
        this.xcoordinate = block.getX() + xposition * this.domenSize;
        this.ycoordinate = block.getY() + yposition * this.domenSize;
        this.pixels = new int[this.domenSize][this.domenSize]; 
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            this.pixels[i][k] = block.getPixel(this.domenSize * xposition + i, this.domenSize * yposition + k);
            }
        }
       
       this.domenParams = new DomenParams(); 
       this.domenParams.domenXCoord = this.xcoordinate;
       this.domenParams.domenYCoord = this.ycoordinate;
       this.domenParams.sameBlockNumber = 0;
       this.domenParams.shift = 0;
       this.domenParams.numberOfConversion = 0;
       this.domenParams.testDelta = this.maxDelta;
    }
    
    public int getX(){
        return this.xcoordinate;
    }
    
    public int getY(){
        return this.ycoordinate;
    }
    
    public void setPixel(int x, int y, int color){
        this.pixels[x][y] = color;
    }
    
    public int[][] getPixels(){
        return this.pixels;
    }
    
    public int getPixel(int x, int y){
        return this.pixels[x][y];
    }
    
    public int getMediumColor(){
        int color = 0;
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            color += this.getPixel(i, k);
            }
        }
        return color / (this.domenSize * this.domenSize);
    }
    
    public Domen turn(){
        Domen ret = new Domen();
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            ret.setPixel(i, k, this.getPixel(k,this.domenSize - 1 -  i));
            }
        }
        return ret;
    }
    
    public Domen mirrorHorizontal(){
        Domen ret = new Domen();
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            ret.setPixel(i, k, this.getPixel(i, this.domenSize - 1 - k));
            }
        }
        return ret;
    }
    
    public Domen mirrorVertical(){
        Domen ret = new Domen();
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            ret.setPixel(i, k, this.getPixel(this.domenSize - 1 - i, k));
            }
        }
        return ret;
    }

    public Domen mirrorPrimDiag(){
        Domen ret = new Domen();
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            ret.setPixel(i, k, this.getPixel(k, i));
            }
        }
        return ret;
    }

    public Domen mirrorSecDiag(){
        Domen ret = new Domen();
        for(int i = 0; i < this.domenSize; ++i){
            for(int k = 0; k < this.domenSize; ++k){
            ret.setPixel(i, k, this.getPixel(this.domenSize - 1 - k, this.domenSize - 1 - i));
            }
        }
        return ret;
    }

    public static int getDomenNumber(Domen dom, byte domensPositionFlag, int imageHeight, int imageWidth){
       int domensPerColumn = imageHeight / IParams.DOMEN_SIZE + 2;
       //TODO:Пересчитать все, кроме 0 и 8
       switch(domensPositionFlag){
           case(0):{
               return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                        dom.getY() / IParams.DOMEN_SIZE;
           }

           case(1):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    return (imageWidth / IParams.DOMEN_SIZE + (dom.getX() == imageWidth - IParams.DOMEN_SIZE ? 1 : 0))
                            * domensPerColumn + dom.getY() / IParams.DOMEN_SIZE;
                }
           }
           case(2):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    return (imageWidth / IParams.DOMEN_SIZE + (dom.getX() == imageWidth - IParams.DOMEN_SIZE ? 2 : 1)) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE;
                }
           }
           case(3):{
                if(dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 1;
                }
           }
           case(4):{
                if(dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 2;
                }
           }
           case(5):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0 && dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    if(dom.getX() % IParams.DOMEN_SIZE != 0 && dom.getY() % IParams.DOMEN_SIZE != 0){
                        return (dom.getX() / IParams.DOMEN_SIZE + 1) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 1;
                    }else{
                        if(dom.getX() % IParams.DOMEN_SIZE != 0){
                            return (dom.getX() / IParams.DOMEN_SIZE + 1) * domensPerColumn +
                                dom.getY() / IParams.DOMEN_SIZE;
                        }else{
                            return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 1;
                        }
                    }
                }
           }
           case(6):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0 && dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    if(dom.getX() % IParams.DOMEN_SIZE != 0 && dom.getY() % IParams.DOMEN_SIZE != 0){
                        return (dom.getX() / IParams.DOMEN_SIZE + 1) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 2;
                    }else{
                        if(dom.getX() % IParams.DOMEN_SIZE != 0){
                            return (dom.getX() / IParams.DOMEN_SIZE + 1) * domensPerColumn +
                                dom.getY() / IParams.DOMEN_SIZE;
                        }else{
                            return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 2;
                        }
                    }
                }
           }
           case(7):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0 && dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    if(dom.getX() % IParams.DOMEN_SIZE != 0 && dom.getY() % IParams.DOMEN_SIZE != 0){
                        return (dom.getX() / IParams.DOMEN_SIZE + 2) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 1;
                    }else{
                        if(dom.getX() % IParams.DOMEN_SIZE != 0){
                            return (dom.getX() / IParams.DOMEN_SIZE + 2) * domensPerColumn +
                                dom.getY() / IParams.DOMEN_SIZE;
                        }else{
                            return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            dom.getY() / IParams.DOMEN_SIZE + 1;
                        }
                    }
                }
           }
           case(8):{
                if(dom.getX() % IParams.DOMEN_SIZE == 0 && dom.getY() % IParams.DOMEN_SIZE == 0){
                   return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                           dom.getY() / IParams.DOMEN_SIZE;
                }else{
                    if(dom.getX() % IParams.DOMEN_SIZE != 0 && dom.getY() % IParams.DOMEN_SIZE != 0){
                        return (imageWidth / IParams.DOMEN_SIZE + (dom.getX() == imageWidth - IParams.DOMEN_SIZE ? 1 : 0))
                                * domensPerColumn + imageHeight / IParams.DOMEN_SIZE + (dom.getY() == imageHeight - IParams.DOMEN_SIZE ? 1 : 0);
                    }else{
                        if(dom.getX() % IParams.DOMEN_SIZE != 0){
                            return (imageWidth / IParams.DOMEN_SIZE + (dom.getX() == imageWidth - IParams.DOMEN_SIZE ? 1 : 0))
                                    * domensPerColumn + dom.getY() / IParams.DOMEN_SIZE;
                        }else{
                            return (dom.getX() / IParams.DOMEN_SIZE) * domensPerColumn +
                            imageHeight / IParams.DOMEN_SIZE + (dom.getY() == imageHeight - IParams.DOMEN_SIZE ? 1 : 0);
                        }
                    }
                }
           }
        }
       return -1;
   }
}
